/*
 * @author Ashish Tomar
 */

package coms6111.astbbw;


import java.text.DateFormat;

import org.apache.log4j.Logger;
import org.w3c.dom.*;
import javax.xml.parsers.*;
import org.xml.sax.*;


public class ResultParser {

	/**
	 * Parse the XML results of a query to Yahoo BOSS, and extract the information
	 * used by this application.
	 * @param result The XML string returned by a BOSS query.
	 * @return A ResultSet object containing a distinct DocumentSet object for
	 * each result in the query.
	 */
	public ResultSet addResult(String result)
	{
		Logger l = Logger.getLogger(ResultParser.class);

		ResultSet re=null;

		try{
			DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
			DocumentBuilder db = factory.newDocumentBuilder();
			InputSource inStream = new InputSource();
			inStream.setCharacterStream(new java.io.StringReader(result));
			Document doc = db.parse(inStream);
			int total_hits, deep_hits, results_sent;
			DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT);

			NodeList resultSetInfo = doc.getElementsByTagName("resultset_web");
			if (1 != resultSetInfo.getLength()) {
				throw new RuntimeException("oh dear"); // XXX
			} else {
				Element e = (Element) resultSetInfo.item(0);
				total_hits = Integer.parseInt(e.getAttribute("totalhits"));
				l.trace("Found " + total_hits + " total hits");
				deep_hits= Integer.parseInt(e.getAttribute("deephits"));
				l.trace("Found " + deep_hits + " deep hits");
				results_sent = Integer.parseInt(e.getAttribute("count"));
				l.trace("Resultset claims to be " + results_sent + " items long");
			}


			NodeList nodes = doc.getElementsByTagName("result");
			int nodesl=nodes.getLength();
			if (nodesl != results_sent) {
				l.fatal("Nodeset length and declared resultset length do not agree");
				throw new RuntimeException(); //
			}
			re = new ResultSet(nodesl);
			re.totalHits = total_hits;
			re.deepHits = deep_hits;

			for (int i = 0; i < nodesl; i++) {
				Element element = (Element) nodes.item(i);

				NodeList url = element.getElementsByTagName("url");
				Element line = (Element) url.item(0);

				re.doc[i].URL=getCharacterDataFromElement(line);


				NodeList title = element.getElementsByTagName("title");
				line = (Element) title.item(0);

				re.doc[i].Title=getCharacterDataFromElement(line);


				NodeList abstrac = element.getElementsByTagName("abstract");
				line = (Element) abstrac.item(0);

				re.doc[i].Abstract=getCharacterDataFromElement(line);

				NodeList tmp = element.getElementsByTagName("date");
				re.doc[i].date = df.parse(tmp.item(0).getTextContent());

				tmp = element.getElementsByTagName("clickurl");
				re.doc[i].clickURL = tmp.item(0).getTextContent();

				tmp = element.getElementsByTagName("size");
				re.doc[i].pageSize = Integer.parseInt(tmp.item(0).getTextContent());

			}




		}
		catch (Exception e) {
			throw new RuntimeException(e);
		}
		return re;
	}
	/**
	 * Extract the character data from an XML element, strip it of emphasis
	 * tags, and return it as a string.
	 * @param e the XML element in question.
	 * @return the character data of this element, with HTML tags stripped.
	 */
	protected static String getCharacterDataFromElement(Element e) {
		Node child = e.getFirstChild();
		if (child instanceof CharacterData) {
			CharacterData cd = (CharacterData) child;
			String tmp = cd.getData();
			return tmp.replaceAll("<(/?)b>", "");
		}
		return "?";
	}

}
